package com.js.auth.client.interceptor;

import com.alibaba.fastjson.JSON;
import com.js.auth.client.annotation.CheckUserToken;
import com.js.auth.client.annotation.IgnoreUserToken;
import com.js.auth.client.config.UserAuthConfig;
import com.js.auth.client.jwt.UserAuthUtil;
import com.js.common.constant.RequestHeaderConstants;
import com.js.common.exception.auth.LoginException;
import com.js.common.response.BaseResponse;
import com.js.core.constants.CommonConstants;
import com.js.core.context.BaseContextHandler;
import com.js.core.util.jwt.IJwtInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author ygl
 * @create 2018-10-30
 * @DESCRIPTION
 *  拦截请求进行token认证
 **/
@Slf4j
public class UserAuthRestInterceptor extends HandlerInterceptorAdapter {

    @Autowired
    private UserAuthUtil userAuthUtil;

    @Autowired
    private UserAuthConfig userAuthConfig;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String method = request.getMethod();
        String requestURI = request.getRequestURI();
        log.info("拦截了请求-----"+requestURI+",类型是-----"+method);
        if (HttpMethod.OPTIONS.matches(method)){
            return super.preHandle(request, response, handler);
        }
        if (!(handler instanceof HandlerMethod))
        {
            return super.preHandle(request, response, handler);
        }

        HandlerMethod handlerMethod = (HandlerMethod) handler;
        // 配置该注解，说明不进行用户拦截
        CheckUserToken annotation = handlerMethod.getBeanType().getAnnotation(CheckUserToken.class);
        IgnoreUserToken ignoreUserToken = handlerMethod.getMethodAnnotation(IgnoreUserToken.class);
        if (annotation == null) {
            annotation = handlerMethod.getMethodAnnotation(CheckUserToken.class);
        }
        if (annotation == null || ignoreUserToken != null) {
            return super.preHandle(request, response, handler);
        } else {
            String token = request.getHeader(userAuthConfig.getTokenHeader());
            if (StringUtils.isEmpty(token)) {
                if (request.getCookies() != null) {
                    for (Cookie cookie : request.getCookies()) {
                        if (cookie.getName().equals(userAuthConfig.getTokenHeader())) {
                            token = cookie.getValue();
                        }
                    }
                }
            }
            /**
             * 对url编码后 空格转换成是%20
             * 现在将编码里面的%20转换成空格
             */
            token = token.replaceAll("%20"," ");
            if (token != null && token.startsWith(RequestHeaderConstants.JWT_TOKEN_TYPE)) {
                token = token.substring(RequestHeaderConstants.JWT_TOKEN_TYPE.length(),token.length());
            }
            try {
                String tenantId = BaseContextHandler.getTenantId();
                /**
                 * 解析token，这里需要认证服务器提供的公钥来解密。
                 */
                IJwtInfo infoFromToken = userAuthUtil.getInfoFromToken(token);
                BaseContextHandler.setToken(token);
                BaseContextHandler.setUsername(infoFromToken.getUniqueName());
                BaseContextHandler.setName(infoFromToken.getName());
                BaseContextHandler.setUserId(infoFromToken.getId());
                BaseContextHandler.setDepartId(infoFromToken.getOtherInfo().get(CommonConstants.JWT_KEY_DEPART_ID));
                BaseContextHandler.setClientId(infoFromToken.getOtherInfo().get(CommonConstants.JWT_KEY_CLIENT_ID));
                String userTenantId = infoFromToken.getOtherInfo().get(CommonConstants.JWT_KEY_TENANT_ID);
                if(StringUtils.isNoneBlank(tenantId)){
                    if(!tenantId.equals(userTenantId)){
                        throw new LoginException("用户不合法!");
                    }
                }
                BaseContextHandler.setTenantID(userTenantId);
            }catch(LoginException ex){
                response.setStatus(HttpStatus.UNAUTHORIZED.value());
                log.error(ex.getMessage(),ex);
                response.setContentType("UTF-8");
                response.getOutputStream().println(JSON.toJSONString(new BaseResponse(ex.getStatus(), ex.getMessage())));
                return false;
            }

            return super.preHandle(request, response, handler);
        }
    }
}
